package com.borqsprocessmanager.receiver;

import java.util.ArrayList;

import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.util.Log;

import com.borqsprocessmanager.App;
import com.borqsprocessmanager.BatteryManagerService;
import com.borqsprocessmanager.ConfigParams;
import com.borqsprocessmanager.Constant;
import com.borqsprocessmanager.db.DBProvider.ProcessTable;
import com.borqsprocessmanager.db.DBProvider.SamplesTable;
import com.borqsprocessmanager.info.BaseBatteryAlsInfo;
import com.borqsprocessmanager.info.BatteryTaskInfo;
import com.borqsprocessmanager.info.NormalBatteryAlsInfo;
import com.borqsprocessmanager.info.ProcessStatsInfo;
import com.borqsprocessmanager.info.SampleInfo;
import com.borqsprocessmanager.interfaces.IRegisterSample;
import com.borqsprocessmanager.sample.ASampleMoudle;
import com.borqsprocessmanager.util.BatteryStatsAnalysis;
import com.borqsprocessmanager.util.PreferencesUtil;

public class BatteryChangedReceiver extends BaseBroadcastReceiver implements
        IRegisterSample {

    private final String TAG = "BatteryChangedReceiver";
    // private final int BASELINE = 1 * 60 * 60 * 1000;

    private BatteryManagerService mService;
    private SampleInfo sampleInfo;
    private ArrayList<ASampleMoudle> sampleList;
    private PreferencesUtil mPreferencesUtil;

    private int preLevel = 0;
    private int curLevel = 0;
    private long preTime = 0;
    private long curTime = 0;

    // Intent.ACTION_BATTERY_CHANGED

    public BatteryChangedReceiver(BatteryManagerService service) {
        mService = service;
        sampleList = new ArrayList<ASampleMoudle>();
        mPreferencesUtil = PreferencesUtil.getInstance(App.mContext);
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        // TODO Auto-generated method stub
        String aciton = intent.getAction();
        // boolean isSample = true;
        if (aciton.equals(Intent.ACTION_BATTERY_CHANGED)) {

            int level = intent.getIntExtra("level", 0);
            Log.v(TAG, "Level===" + level);
            if (level != 0 && level != curLevel) {
                long time = getNowTime();
                long intervalTime = 0;
                preLevel = curLevel;
                preTime = curTime;
                curLevel = level;
                curTime = time;
                intervalTime = curTime - preTime;
                mService.setCurBatteryLevel(curLevel);// 保存起来当前curlevel
                Log.v(TAG, "onReceive_ACTION_BATTERY_CHANGED_preLevel==="
                        + preLevel);
                Log.v(TAG, "onReceive_ACTION_BATTERY_CHANGED_curLevel==="
                        + curLevel);
                Log.v(TAG, "onReceive_ACTION_BATTERY_CHANGED_preTime==="
                        + preTime);
                Log.v(TAG, "onReceive_ACTION_BfolderATTERY_CHANGED_curTime==="
                        + curTime);
                Log.v(TAG, "(curTime - preTime)===" + intervalTime);
                Log.v(TAG, "POWER_MIN_TIME_BASELINE==="
                        + ConfigParams.POWER_MIN_TIME_BASELINE);

                if (curLevel < preLevel && mService.isSample()) {
                    BaseBatteryAlsInfo batteryAlsInfo = mService
                            .getBatteryAlsInfo();
                    if (BatteryStatsAnalysis.isOutrideBaseLine(intervalTime,
                            batteryAlsInfo)) {
                        Log.v(TAG, "!!!!!!!!!!!!!!!!Exceed!!!!!!!!!!!!!!!!!");
                        ArrayList<ProcessStatsInfo> reslist = sampleProcess(
                                sampleList,
                                ASampleMoudle.TYPE_GETDATA_AND_CONTINUE);
                        if (reslist != null && reslist.size() > 0) {
                            sampleInfo = upDataSampleInfo(sampleInfo);
                            Log.v(TAG, "sampleId===" + sampleInfo.sampleId);
                            saveProcessInfoOfDB(context, reslist);
                            saveSampleInfoOfDB(context, sampleInfo);
                            mPreferencesUtil.putBoolean(
                                    Constant.KEY_IS_NEWDATA, true);
                            mPreferencesUtil.putInt(Constant.KEY_INIT_ARGTIME,
                                    0);
                        } else {
                            initArgTime(batteryAlsInfo);
                        }
                    } else {
                        batteryAlsInfo.eorrCount = 0;
                        BatteryStatsAnalysis.setArgTime(intervalTime,
                                batteryAlsInfo);
                        // 未超过baseline就继续采集，不取数据
                        sampleProcess(sampleList, ASampleMoudle.TYPE_CONTINUE);
                    }
                } else {
                    // 继续采集，不取数据
                    sampleProcess(sampleList, ASampleMoudle.TYPE_CONTINUE);
                }
                mService.initState();
            }
        }
    }

    private ArrayList<ProcessStatsInfo> sampleProcess(
            ArrayList<ASampleMoudle> sampleList, int type) {
        com.borqsprocessmanager.util.Log.v(TAG, "sampleProcess_" + type);
        ArrayList<ProcessStatsInfo> reslist = new ArrayList<ProcessStatsInfo>();

        for (ASampleMoudle sampleMoudle : sampleList) {
            ArrayList<ProcessStatsInfo> list = sampleMoudle.sample(
                    mService.getSimpleId(), type,
                    mService.getWhiteMap().whiteMap);
            // Log.v(TAG, "list.size===" + list.size());
            if (list != null && list.size() > 0) {
                reslist.addAll(list);
            }
        }
        Log.v(TAG, "reslist.size===" + reslist.size());
        return reslist;
    }

    /**
     * 更新SapleInfo信息，如果null就新建。 如果与当前sampleId不一致，就全部更新。 如果一致，只更新end信息。
     * 
     * @param sampleInfo
     * @return SampleInfo
     */
    private SampleInfo upDataSampleInfo(SampleInfo sampleInfo) {
        if (sampleInfo == null) {
            sampleInfo = new SampleInfo();
        }
        int simpleId = mService.getSimpleId();
        if (sampleInfo.sampleId != mService.getSimpleId()) {
            sampleInfo.setSampleId(simpleId);
            sampleInfo.setStartTime(preTime);
            sampleInfo.setStartLevel(preLevel);
        }
        sampleInfo.setEndTime(curTime);
        sampleInfo.setEndLevel(curLevel);
        return sampleInfo;
    }

    private void saveProcessInfoOfDB(Context context,
            ArrayList<ProcessStatsInfo> list) {
        ContentValues[] values = new ContentValues[list.size()];
        for (int i = 0; i < values.length; i++) {
            ProcessStatsInfo info = list.get(i);
            ContentValues value = new ContentValues();
            // value.put(ProcessTable.PID, info.pid);
            value.put(ProcessTable.UID, info.uid);
            value.put(ProcessTable.APPNAME_NAME, info.appName);
            value.put(ProcessTable.PKG_NAME, info.packageName);
            value.put(ProcessTable.PROCESS_NAME, info.processName);
            value.put(ProcessTable.IS_SYSTEM, info.isSystem);
            value.put(ProcessTable.RATIO, info.ratio);
            value.put(ProcessTable.TX_BYTES, info.tx);
            value.put(ProcessTable.RX_BYTES, info.rx);
            value.put(ProcessTable.TOTAL_BYTES, info.total);
            value.put(ProcessTable.SAMPLE_ID, info.sampleId);
            value.put(ProcessTable.TYPE, info.type);
            values[i] = value;
        }
        context.getContentResolver().bulkInsert(ProcessTable.CONTENT_URI,
                values);
    }

    /**
     * 把sampleInfo存入DB
     * 
     * @param context
     * @param sampleInfo
     */
    private void saveSampleInfoOfDB(Context context, SampleInfo sampleInfo) {
        ContentValues values = new ContentValues();
        values.put(SamplesTable._ID, sampleInfo.sampleId);
        values.put(SamplesTable.START_TIME, sampleInfo.startTime);
        values.put(SamplesTable.END_TIME, sampleInfo.endTime);
        values.put(SamplesTable.START_LEVEL, sampleInfo.startLevel);
        values.put(SamplesTable.END_LEVEL, sampleInfo.endLevel);
        context.getContentResolver().insert(SamplesTable.CONTENT_URI, values);
    }

    private long getNowTime() {
        return System.currentTimeMillis();
        // return SystemClock.elapsedRealtime();
    }

    public void registerSample(ASampleMoudle sample) {
        sampleList.add(sample);
    }

    /**
     * 如果多次超出范围但没有异常内容，就清空用户平均待机时间
     * 
     * @param info
     */
    public void initArgTime(BaseBatteryAlsInfo info) {
        com.borqsprocessmanager.util.Log.v(TAG, "initArgTime");
        // int count = mPreferencesUtil.getInt(Constant.KEY_INIT_ARGTIME, 0) +
        // 1;
        info.eorrCount++;
        if (info.eorrCount < 5) {
            mPreferencesUtil.putInt(Constant.KEY_INIT_ARGTIME, info.eorrCount);
        } else {
            mPreferencesUtil.putInt("init", 0);
            com.borqsprocessmanager.util.Log.v(TAG, "initArgTime_count < 3");
            BatteryStatsAnalysis.initArgTime(info);
            info.eorrCount = 0;
            // mPreferencesUtil.putInt(Constant.KEY_INIT_ARGTIME, 0);
        }
    }
}
